﻿using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Data.Linq;

namespace StoragePeriod.Data
{

    public static class ActionType
    {
        public const string Update = "Update";
        public const string Delete = "Delete";
        public const string Insert = "Insert";
    }

    public static class LinqUtility
    {
        public static StoragePeriodDataContext LinqContext { get; set; }

        public static CMSCateringDataContext LinqContextCMS { get; set; }
        /// <summary>
        /// 插入方法
        /// </summary>
        /// <param name="entity">实体</param>
        public static void Insert(object entity)
        {
            UpdateContextData(null, ActionType.Insert, entity, null, null, null);
        }
        /// <summary>
        /// 删除方法
        /// </summary>
        /// <param name="tableType">表类型</param>
        /// <param name="where">查询表达式</param>
        /// <param name="wherePar">参数</param>
        public static void Delete(Type tableType, string where, params object[] wherePar)
        {
            UpdateContextData(tableType, ActionType.Delete, null, where, null, wherePar);
        }
        /// <summary>
        /// 更新方法
        /// </summary>
        /// <param name="entity">实体</param>
        /// <param name="where">查询表达式</param>
        /// <param name="wherePar">参数</param>
        public static void Update(Type tableType, object entity, string where, DataContext LinqContext, params object[] wherePar)
        {
            UpdateContextData(tableType, ActionType.Update, entity, where, LinqContext, wherePar);
        }
        /// <summary>
        /// 数据实体操作
        /// </summary>
        /// <param name="tableType">表类型</param>
        /// <param name="actionType"></param>
        /// <param name="entity"></param>
        /// <param name="where"></param>
        /// <param name="wherePar"></param>
        public static void UpdateContextData(Type tableType, string actionType, object entity, string where, DataContext dataContext = null, params object[] wherePar)
        {
            if (dataContext == null)
                dataContext = LinqContext;
                        
            if (tableType == null)
                tableType = entity.GetType();

            var linqTable = dataContext.GetTable(tableType);

            switch (actionType)
            {
                case ActionType.Insert:
                    linqTable.InsertOnSubmit(entity);
                    break;
                case ActionType.Delete:
                    var resDeleteList = linqTable.Where(where, wherePar);
                    foreach (var item in resDeleteList)
                    {
                        linqTable.DeleteOnSubmit(item);
                        // break;
                    }
                    break;
                case ActionType.Update:
                    var resUpdateList = linqTable.Where(where, wherePar);
                    foreach (var item in resUpdateList)
                    {
                        MajorEntity(item, entity);
                        break;
                    }
                    break;
            }

            try
            {
                dataContext.SubmitChanges(System.Data.Linq.ConflictMode.ContinueOnConflict);
            }
            catch (System.Data.Linq.ChangeConflictException ex)
            {
                foreach (System.Data.Linq.ObjectChangeConflict occ in dataContext.ChangeConflicts)
                {
                    //以下是解决冲突的三种方法，选一种即可
                    // 使用当前数据库中的值，覆盖Linq缓存中实体对象的值
                    occ.Resolve(System.Data.Linq.RefreshMode.OverwriteCurrentValues);
                    // 使用Linq缓存中实体对象的值，覆盖当前数据库中的值
                    occ.Resolve(System.Data.Linq.RefreshMode.KeepCurrentValues);
                    // 只更新实体对象中改变的字段的值，其他的保留不变
                    occ.Resolve(System.Data.Linq.RefreshMode.KeepChanges);
                }
                // 这个地方要注意，Catch方法中，我们前面只是指明了怎样来解决冲突，这个地方还需要再次提交更新，这样的话，值    //才会提交到数据库。
                dataContext.SubmitChanges();
            }

            //try
            //{
            //    dataContext.SubmitChanges();
            //}
            //catch (Exception ex)
            //{
            //    throw ex;
            //}
            //finally
            //{
            //   // LinqContext.Dispose();
            //}

        }
        public static void MajorEntity(object item, object entity)
        {
            Type entityType = entity.GetType();
            item.GetType().GetProperties().ToList().ForEach(p =>
            {
                var field = entityType.GetProperty(FixPropertyName(p.Name));
                if (field != null)
                {
                    p.SetValue(item, field.GetValue(entity, null), null);
                }
            });
        }

        public static string FixPropertyName(string p)
        {
            return p;
        }
    }
}
